﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using DotNet.Utilities;
using System.Text.RegularExpressions;
using Beauty.BLL;
using Beauty.Model;
using System.Diagnostics;
using System.Xml;

namespace Picdownload
{
    public partial class Form1 : Form
    {
        private string destDir;//目标文件夹

        // Token: 0x17000030 RID: 48
        public string Detial_Pattern
        {
            // Token: 0x06000089 RID: 137 RVA: 0x00004809 File Offset: 0x00002A09
            get;
            // Token: 0x0600008A RID: 138 RVA: 0x00004811 File Offset: 0x00002A11
            set;
        }

        // Token: 0x1700002D RID: 45
        public int DownThreadNum
        {
            // Token: 0x06000081 RID: 129 RVA: 0x000043D5 File Offset: 0x000025D5
            get;
            // Token: 0x06000082 RID: 130 RVA: 0x000043DD File Offset: 0x000025DD
            set;
        }

        // Token: 0x1700002F RID: 47
        public string List_Pattern
        {
            // Token: 0x06000087 RID: 135 RVA: 0x000047F8 File Offset: 0x000029F8
            get;
            // Token: 0x06000088 RID: 136 RVA: 0x00004800 File Offset: 0x00002A00
            set;
        }

        // Token: 0x1700002C RID: 44
        public int MainThreadNum
        {
            // Token: 0x0600007F RID: 127 RVA: 0x000043C4 File Offset: 0x000025C4
            get;
            // Token: 0x06000080 RID: 128 RVA: 0x000043CC File Offset: 0x000025CC
            set;
        }



        public Form1()
        {
            InitializeComponent();
        }

        private void btnSelectDestDir_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dlg = new FolderBrowserDialog();
            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtDestDir.Text = dlg.SelectedPath;
            }
        }





        private string DownloadImage(string objURL)
        {
            //UrlRefer：这个图片是从哪个页面启动下载的

            //Path.GetFileName(objURL)得到“1.jpg”
            //Path.Combine是把destDir和1.jpg拼接起来
            try
            {


                GC.Collect();
                int i = 0;
                do
                {
                    i++;
                } while (i < 1000);
                txtLog.AppendText("\r\n" + "准备下载图片--" + DateTime.Now);
                string destFile = Path.Combine(destDir, Path.GetFileName(objURL));
                string thumbFile = Path.Combine(txt_thumb.Text, Path.GetFileName(objURL));
                //要保存的文件名
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(objURL);
                //request.Referer = "http://www.tutu12345.net/";//欺骗服务器说“是从百度发出的请求”
                //request.Method = "GET";
                //request.KeepAlive = true;
                //request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
                //request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.75 Safari/537.36";

                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        using (Stream stream = response.GetResponseStream())
                        using (Stream fsStream = new FileStream(destFile, FileMode.Create))
                        {
                            stream.CopyTo(fsStream);
                        }
                        txtLog.AppendText("\r\n" + "下载完毕--" + DateTime.Now);
                    }
                    else
                    {
                        throw new Exception("下载" + objURL + "失败，错误码：" + response.StatusCode);
                    }
                }
                //WebClient mywebclient = new WebClient();
                //mywebclient.
                //try
                //{
                //    mywebclient.DownloadFile(objURL, destFile);
                //}
                //catch (Exception ex)
                //{
                //     txtLog.AppendText("\r\n" +"下载发生异常--" + ex.Message);
                //}
                //finally
                //{
                //    mywebclient.Dispose();

                //}

                txtLog.AppendText("\r\n" + "下载完毕--" + DateTime.Now);

                //生成缩略图
                Utilities.ImageHelper.MakeThumbnail(destFile, thumbFile, 250, 360, "Cut");
                return Path.GetFileName(destFile);

            }
            catch (Exception ex)
            {
                txtLog.AppendText("\r\n下载图片发生异常原因：" + ex.Message);
                txtLog.AppendText("\r\n详细异常原因：" + ex.ToString());
                return ex.Message;
            }
            //string destPath = Path.Combine(@"H:\C#", Path.GetFileName(@"C:\歌曲\宿敌.avi"));
            //System.IO.File.Copy(@"C:\歌曲\宿敌.avi", destPath);
        }

        /// <summary>
        /// 获取列表页标题和href链接
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        private Dictionary<string, string> GetAlbumsData(string url)
        {
            txtLog.AppendText("\r\n" + "获取列表页中....");

            HttpHelper http = new HttpHelper();
            HttpItem item = new HttpItem()
            {
                URL = url,//URL     必需项
                Encoding = null,//编码格式（utf-8,gb2312,gbk）     可选项 默认类会自动识别
                //Encoding = Encoding.Default,
                Method = "get",//URL     可选项 默认为Get
                Timeout = 100000,//连接超时时间     可选项默认为100000
                ReadWriteTimeout = 30000,//写入Post数据超时时间     可选项默认为30000
                IsToLower = false,//得到的HTML代码是否转成小写     可选项默认转小写
                Cookie = "",//字符串Cookie     可选项
                UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",//用户的浏览器类型，版本，操作系统     可选项有默认值
                Accept = "text/html, application/xhtml+xml, */*",//    可选项有默认值
                ContentType = "text/html",//返回类型    可选项有默认值
                Referer = "http://www.apic.in",//来源URL     可选项
                Allowautoredirect = true,//是否根据３０１跳转     可选项
                Connectionlimit = 1024,//最大连接数     可选项 默认为1024
                CookieCollection = new System.Net.CookieCollection(),//可以直接传一个Cookie集合进来
            };


            //得到HTML代码
            HttpResult result = http.GetHtml(item);
            //取出返回的Cookie
            string cookie = result.Cookie;
            //返回的Html内容
            string html = result.Html;
            Dictionary<string, string> dics = new Dictionary<string, string>();
            bool isConvert = false;
            if (txt_url.Text.IndexOf(Config.JIEPAI_SITE) != -1)
            {
                //街拍这个网站html只返回了相对路径，所以需要转换为绝对路径
                isConvert = true;
            }
            Uri u = new Uri(txt_url.Text);
            if (result.StatusCode == System.Net.HttpStatusCode.OK)
            {
                //表示访问成功，具体的大家就参考HttpStatusCode类
                string pattern = List_Pattern;
                MatchCollection mc = Regex.Matches(html, pattern);
                foreach (Match m in mc)
                {
                    if (m.Success)
                    {
                        if (m.Groups["href"].Value.IndexOf("http://") == -1)
                        {
                            //页面只有相对路径，这里需要加上网站的绝对地址

                            dics.Add(m.Groups["title"].Value, u.Host + m.Groups["href"].Value);

                        }
                        else
                        {
                            dics.Add(m.Groups["title"].Value, m.Groups["href"].Value);
                        }
                        //加入集合数组
                        //if (isConvert)
                        //{
                        //    dics.Add(m.Groups["title"].Value, Config.JIEPAI_SITE + m.Groups["href"].Value);

                        //}
                        //else
                        //{
                        //    dics.Add(m.Groups["title"].Value, m.Groups["href"].Value);

                        //}
                        //this.TextBox3.Text += m.Groups["href"].Value + "|" + m.Groups["name"].Value + "\n";
                    }
                }

            }
            //表示StatusCode的文字说明与描述
            string statusCodeDescription = result.StatusDescription;
            return dics;
        }

        /// <summary>
        /// 获取详情页的图片地址
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        private List<string> GetDetialImagesInfo(string url)
        {
            txtLog.AppendText("\r\n" + "获取详情页图片地址中....");
            HttpHelper http = new HttpHelper();

            HttpItem item = new HttpItem()
            {
                URL = url.IndexOf("http://") == -1 ? "http://" + url : url,//URL     必需项
                Encoding = null,//编码格式（utf-8,gb2312,gbk）     可选项 默认类会自动识别
                //Encoding = Encoding.Default,
                Method = "get",//URL     可选项 默认为Get
                Timeout = 100000,//连接超时时间     可选项默认为100000
                ReadWriteTimeout = 30000,//写入Post数据超时时间     可选项默认为30000
                IsToLower = false,//得到的HTML代码是否转成小写     可选项默认转小写
                Cookie = "",//字符串Cookie     可选项
                UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",//用户的浏览器类型，版本，操作系统     可选项有默认值
                Accept = "text/html, application/xhtml+xml, */*",//    可选项有默认值
                ContentType = "text/html",//返回类型    可选项有默认值
                Referer = "http://www.tutu12345.net",//来源URL     可选项
                Allowautoredirect = true,//是否根据３０１跳转     可选项
                Connectionlimit = 1024,//最大连接数     可选项 默认为1024
                CookieCollection = new System.Net.CookieCollection(),//可以直接传一个Cookie集合进来
            };


            //得到HTML代码
            HttpResult result = http.GetHtml(item);
            //取出返回的Cookie
            string cookie = result.Cookie;
            //返回的Html内容
            string html = result.Html;
            List<string> urls = new List<string>();//对于分页图片的页面存放地址
            List<string> srcs = new List<string>();//存放图片

            bool isConvert = false;
            if (txt_url.Text.IndexOf(Config.JIEPAI_SITE) != -1)
            {
                //街拍这个网站html只返回了相对路径，所以需要转换为绝对路径
                isConvert = true;
            }
            //有多少页循环多少次来获取每页的图片地址
            string expand = url.IndexOf(".shtml") == -1 ? "html" : "shtml";
            if (result.StatusCode == System.Net.HttpStatusCode.OK)
            {
                //表示访问成功，具体的大家就参考HttpStatusCode类
                string pattern = Detial_Pattern;
                MatchCollection mc = Regex.Matches(html, pattern);
                foreach (Match m in mc)
                {
                    if (m.Success)
                    {
                        if (m.Groups["countPage"].Value != "")
                        {
                            Log("此详情页是分页，开始采集分页地址");
                            int pageCount = Convert.ToInt32(m.Groups["countPage"].Value);
                            urls.Add(url);
                            //此详情页图片有分页，需要获取分页地址
                            for (int i = 2; i <= pageCount; i++)
                            {
                                urls.Add(url.Replace(".html", "_" + i + "." + expand));
                            }
                            //循环获取每个页面的图片
                            Log("采集完毕，开始获取单页面图片地址");
                            srcs = GetImgSrcsByListPageView(urls);
                            Log("单页面图片获取完毕");
                            continue;
                        }
                        //加入集合数组
                        if (m.Groups["src"].Value.IndexOf("http://") == -1)
                        {
                            srcs.Add(txt_url.Text + m.Groups["src"].Value);

                        }
                        else
                        {
                            srcs.Add(m.Groups["src"].Value);
                        }
                    }
                }

            }
            return srcs;
        }
        private void Log(string log)
        {
            txtLog.AppendText("\r\n" + log);

        }
        /// <summary>
        /// 获取每个页面的图片地址
        /// </summary>
        /// <param name="urls">地址列表</param>
        /// <returns></returns>
        private List<string> GetImgSrcsByListPageView(List<string> urls)
        {
            HttpHelper http = new HttpHelper();
            HttpItem item = new HttpItem()
            {
                URL = "循环填充",//URL     必需项
                Encoding = null,//编码格式（utf-8,gb2312,gbk）     可选项 默认类会自动识别
                //Encoding = Encoding.Default,
                Method = "get",//URL     可选项 默认为Get
                Timeout = 100000,//连接超时时间     可选项默认为100000
                ReadWriteTimeout = 30000,//写入Post数据超时时间     可选项默认为30000
                IsToLower = false,//得到的HTML代码是否转成小写     可选项默认转小写
                Cookie = "",//字符串Cookie     可选项
                UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",//用户的浏览器类型，版本，操作系统     可选项有默认值
                Accept = "text/html, application/xhtml+xml, */*",//    可选项有默认值
                ContentType = "text/html",//返回类型    可选项有默认值
                Referer = "http://www.tutu12345.net",//来源URL     可选项
                Allowautoredirect = true,//是否根据３０１跳转     可选项
                Connectionlimit = 1024,//最大连接数     可选项 默认为1024
                CookieCollection = new System.Net.CookieCollection(),//可以直接传一个Cookie集合进来
            };
            List<string> srcs = new List<string>();

            foreach (var url in urls)
            {
                item.URL = url.IndexOf("http://") == -1 ? "http://" + url : url;
                //得到HTML代码
                HttpResult result = http.GetHtml(item);
                //返回的Html内容
                string html = result.Html;

                if (result.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    //表示访问成功，具体的大家就参考HttpStatusCode类
                    string pattern = Detial_Pattern;
                    MatchCollection mc = Regex.Matches(html, pattern);
                    foreach (Match m in mc)
                    {
                        if (m.Success)
                        {

                            //加入集合数组
                            if (m.Groups["src"].Value.IndexOf("http://") == -1)
                            {
                                //页面只有相对路径，这里需要加上网站的绝对地址

                                srcs.Add(txt_url.Text + m.Groups["src"].Value);
                            }
                            else
                            {
                                srcs.Add(m.Groups["src"].Value);
                            }
                            //srcs.Add(Config.JIEPAI_SITE + m.Groups["src"].Value);

                        }
                    }

                }
            }


            return srcs;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            System.Net.ServicePointManager.DefaultConnectionLimit = 150;

            string url = txt_url.Text;
            if (string.IsNullOrEmpty(url))
            {
                MessageBox.Show("请输入URL");
                return;
            }
            destDir = txtDestDir.Text;
            if (string.IsNullOrEmpty(destDir))
            {
                MessageBox.Show("请选择要保存的文件夹");
                return;
            }

            //d:\a\
            if (!destDir.EndsWith("\\"))
            {
                destDir = destDir + "\\";
            }
            Control.CheckForIllegalCrossThreadCalls = false;
            Thread thread = new Thread(() =>
            {
                Process();
            });
            thread.Start();



        }
        picalbumBLL bllAlbum = new picalbumBLL();
        picmainBLL bllMain = new picmainBLL();
        public int Skip { get { return 0; } }
        /// <summary>
        /// 获取图片和下载图片主逻辑
        /// </summary>
        private void Process()
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            int mainThreadNum = this.MainThreadNum;
            MainThreadNum = mainThreadNum + 1;
            lab_main_thread.Text = "套图线程数量：" + this.MainThreadNum;

            Dictionary<string, string> albums = GetAlbumsData(txt_url.Text);
            int index = 0;
            foreach (var key in albums.Keys)
            {
                index++;
                if (index > this.Skip)
                {
                    //插入套图
                    picalbum album = new picalbum()
                    {
                        ClassId = Convert.ToInt32(combo_class.SelectedValue),
                        CoverId = 1,
                        Description = key,
                        Title = key,
                        UserId = 1,
                    };
                    List<string> srcs = GetDetialImagesInfo(albums[key]);//获得套图的所有图片src链接

                    int newId = bllAlbum.Add(album, "GetIndentity");
                    srcs.Add(newId.ToString());
                    txtLog.AppendText("\r\n" + "套图插入完毕" + DateTime.Now);

                    Thread thread = new Thread(() => Down(srcs));
                    thread.Start();
                    //开线程取下载图片 这个过程比较耗时
                }




            }
            watch.Stop();
            while (this.DownThreadNum > 1)
            {
            }
            mainThreadNum = this.MainThreadNum;
            this.MainThreadNum = mainThreadNum - 1;
            this.lab_main_thread.Text = "套图线程数量：" + this.MainThreadNum;
            MessageBox.Show("下载工作完成本次耗时：" + watch.ElapsedMilliseconds / 1000L / 60L + "分钟");
        }


        private void Down(List<string> srcs)
        {


            int downThreadNum = this.DownThreadNum;
            this.DownThreadNum = downThreadNum + 1;
            this.lab_down_thread.Text = "下载线程数量：" + this.DownThreadNum;
            List<picmain> pics = new List<picmain>();
            int albumId = Convert.ToInt32(srcs[srcs.Count - 1]);
            int index = 0;
            foreach (var item in srcs)
            {
                index++;
                if (index == srcs.Count)
                {
                    break;
                }
                string fileName = DownloadImage(item);//根据图片地址下载图片
                pics.Add(new picmain()
                {
                    AlbumId = albumId,
                    Src = fileName,
                    Userid = 1,
                    SortId = 1
                });
            }
            //下载完成后 插入图片
            txtLog.AppendText("\r\n" + "即将插入图片" + DateTime.Now);
            int newPicId = bllMain.Add(pics);
            if (newPicId > 0)
            {
                //图片插入后再去更新下套图的封面
                bllAlbum.Update(albumId, newPicId);//将最后一张图片作为默认封面
            }
            txtLog.AppendText("\r\n" + "图片插入完毕" + DateTime.Now);
            downThreadNum = this.DownThreadNum;
            this.DownThreadNum = downThreadNum - 1;
            this.lab_down_thread.Text = "下载线程数量：" + this.DownThreadNum;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            System.Web.Script.Serialization.JavaScriptSerializer jss = new System.Web.Script.Serialization.JavaScriptSerializer();





            this.combo_class.DataSource = new picclassBLL().GetAllList().Tables[0];
            this.combo_class.ValueMember = "ClassId";
            this.combo_class.DisplayMember = "ClassName";
            XmlDocument doc = new XmlDocument();
            try
            {
                doc.Load("spider.xml");
            }
            catch (FileNotFoundException ex)
            {
                MessageBox.Show("配置文件不存在" + ex.Message);
            }
            XmlNodeList nodeList = doc.SelectSingleNode("settings").SelectSingleNode("spider").SelectSingleNode("regex").ChildNodes;
            this.List_Pattern = nodeList.Item(1).InnerText;
            this.Detial_Pattern = nodeList.Item(3).InnerText;

        }
    }
}
